package sicnu.cs.aps.rest;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import sicnu.cs.aps.common.Constants;
import sicnu.cs.aps.common.ResultInfo;
import sicnu.cs.aps.common.ResultInfoUtil;
import sicnu.cs.aps.common.annotations.OperLog;
import sicnu.cs.aps.common.enums.OperEnum;
import sicnu.cs.aps.common.util.RequestUtil;
import sicnu.cs.aps.domain.entity.User;
import sicnu.cs.aps.service.ISendMailService;
import sicnu.cs.aps.service.IUserService;
import sicnu.cs.aps.service.impl.RedisService;

import java.util.List;
import java.util.Map;

import static sicnu.cs.aps.common.Constants.REDIS_EMAIL_CODE;
import static sicnu.cs.aps.common.util.RequestUtil.getCurrentUserId;
import static sicnu.cs.aps.common.util.ValidateUtils.*;


/**
 * @author caike
 */
@Slf4j
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
@Api(tags = {"用户模块"})
public class UserResource {
    private final IUserService userService;
    private final RedisService redisService;
    private final ISendMailService sendMailService;
    private final PasswordEncoder passwordEncoder;
    private final static String NEW_PASSWORD = "newPassword";
    private final static String OLD_PASSWORD = "oldPassword";

    @ApiOperation(value = "发送邮箱验证码(邮箱是可选项,默认是发送给登录账户的邮箱")
    @GetMapping("/emailCode/{email}")
//    @OperLog(module = "用户功能模块", type = OperEnum.OTHER, description = "用户发送邮箱验证码")
    @OperLog(type = OperEnum.OTHER)
    public ResultInfo<Void> sendLoginByEmailCode(@PathVariable(required = false) String email) {
        if (email == null) {
            User user = userService.findUser(getCurrentUserId());
            email = user.getEmail();
        } else if (!isValidEmail(email)) {
            return ResultInfoUtil.buildError("邮箱格式错误");
        }
        // 发送验证码邮件(生成6位随机数)
        String code = createValidateCode();
        // 保存验证码
        redisService.cacheValue(REDIS_EMAIL_CODE + email, code, 60 * 5);
        sendMailService.sendValidateCodeEmail(email, code);
        return ResultInfoUtil.buildSuccess();
    }


    @ApiOperation(value = "修改密码", notes = "参数：newPassword、oldPassword")
    @PutMapping("/password")
    @OperLog(type = OperEnum.UPDATE)
    public ResultInfo<Void> updatePassword(@RequestBody Map<String, String> param) {
        if (!isValidStrParams(param, NEW_PASSWORD, OLD_PASSWORD)) {
            return ResultInfoUtil.buildError();
        }
        Long userid = RequestUtil.getCurrentUserId();
        String password = userService.findPassword(userid);
        if (passwordEncoder.matches(param.get(OLD_PASSWORD), password)) {
            userService.resetPassword(userid, param.get(NEW_PASSWORD));
        } else {
            return ResultInfoUtil.buildError("密码错误");
        }
        return ResultInfoUtil.buildSuccess();
    }

    @ApiOperation(value = "导入学生用户", notes = "参数：file")
    @PostMapping("/import/student")
    @OperLog(type = OperEnum.ADD)
    public ResultInfo<List<String>> importStudent(@RequestPart("file") MultipartFile file) throws Exception {
        if (file == null){
            return ResultInfoUtil.buildError("传入文件为空");
        }
        List<String> result = userService.importUser(file, Constants.USER_IMPORT_STUDENT);
        return solveImportMessage(result);
    }

    @ApiOperation(value = "导入教师用户", notes = "参数：file")
    @PostMapping("/import/teacher")
    @OperLog(type = OperEnum.ADD)
    public ResultInfo<List<String>> importTeacher(@RequestPart("file") MultipartFile file) throws Exception {
        if (file == null){
            return ResultInfoUtil.buildError("传入文件为空");
        }
        List<String> result = userService.importUser(file, Constants.USER_IMPORT_TEACHER);
        return solveImportMessage(result);
    }

    /**
     * 导入用户返回信息处理
     * @param result service返回信息
     * @return 返回前端的信息
     */
    private ResultInfo<List<String>> solveImportMessage(List<String> result) {
        if (result == null){
            return ResultInfoUtil.buildError("文件格式有误,(请检查学号)");
        }
        int flag = Integer.parseInt(result.get(0));
        if (flag == Constants.USER_IMPORT_STATE_SUCCESS){
            return ResultInfoUtil.buildSuccess("用户导入成功");
        }else if (flag == Constants.USER_IMPORT_STATE_PARTIAL_SUCCESS){
            result.remove(0);
            return ResultInfoUtil.buildSuccess("用户导入部分成功",result);
        } else {
            result.remove(0);
            return ResultInfoUtil.buildError("用户导入失败",result);
        }
    }


}
